﻿using Avalonia;

using LightCAD.Core;
using LightCAD.Runtime.Editor;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LightCAD.Runtime
{
    public class DocumentScene
    {
        public static Box2d PastingBox { get; set; }
        public static List<Element> PastingElements { get; set; }
        public static Element HoveredElement { get; set; }

        public static List<Element> SelectedElements { get; } = new List<Element>();
        public static double DragX { get; set; }
        public static double DragY { get; set; }
        public static int Draw(LcDocument doc, SKCanvas canvas)
        {
            //var matrix= ElementDrawer.WorldToScrMatrix();
            //canvas.SetMatrix(matrix);
            var dcount = 0;
            var scope = ElementDrawer.GetVPortScope();
            var scrScope = scope.Item1;
            var worldScope = scope.Item2;
            var zoom = scrScope.Width / worldScope.Width;
            var count = doc.ModelSpace.Elements.Count;
            var rnd = new Random();
            //由于渲染线程和UI是不同的线程，这里需要考虑集合的动态变化
            for (var i = 0; i < count; i++)
            {
                if (i > doc.ModelSpace.Elements.Count - 1) break;
                var element = doc.ModelSpace.Elements[i];
                if (!element.BoundingBox.IntersectWith(worldScope)) continue;


                //当元素量巨大时10-50万个，多数的元素已经被缩小到很小，视觉效果上无需都显示
                var zoomSize = Math.Max(element.BoundingBox.Width * zoom, element.BoundingBox.Height * zoom);
                if (zoomSize < 4 && i % 2 != 0)//1/2概率不显示
                {
                    continue;
                }
                else if (zoomSize < 2 && i % 4 != 0)//3/4概率不显示
                {
                    continue;
                }
                else if (zoomSize < 1 && i % 8 != 0)//7/8概率不显示
                {
                    continue;
                }
                else if (zoomSize < 0.5 && i % 16 != 0)//15/16概率不显示
                {
                    continue;
                }

                element.Draw(canvas);
                dcount++;
            }
            return dcount;
        }
        public static void DrawDrags(LcDocument doc, SKCanvas canvas)
        {
            //var matrix= ElementDrawer.WorldToScrMatrix();
            //canvas.SetMatrix(matrix);

            //多线程需要考虑动态变化
            var count = SelectedElements.Count;
            for (var i = 0; i < count; i++)
            {
                if (i > SelectedElements.Count - 1) break;
                SelectedElements[i].Draw(canvas, new Vector2d(DragX, DragY));
            }
        }

        public static void SelectElements(List<Element> elements)
        {
            foreach (var ele in elements)
            {
                ele.IsSelected = true;
                SelectedElements.Add(ele);
            }
        }
        public static List<Element> RectSelects(ElementContainer container, Box2d selectBox, bool isInclude)
        {
            var elements = new List<Element>();
            for (var i = container.Elements.Count - 1; i >= 0; i--)
            {
                var ele = container.Elements[i];

                var selected = isInclude ? ele.IncludeByBox(selectBox) : ele.IntersectWithBox(selectBox);
                if (selected)
                {
                    if (!ele.IsSelected)
                    {
                        ele.IsSelected = true;
                        elements.Add(ele);
                    }
                }
            }
            SelectedElements.AddRange(elements);
            return elements;
        }
        public static Element HitUnselect(ElementContainer container, Vector2d hitPoint, double selectSize)
        {
            for (var i = container.Elements.Count - 1; i >= 0; i--)
            {
                var ele = container.Elements[i];
                var testBox = new Box2d(new Vector2d(hitPoint.X - selectSize, hitPoint.Y - selectSize), selectSize * 2, selectSize * 2);
                var intersected = ele.IntersectWithBox(testBox);
                if (intersected)
                {
                    if (ele.IsSelected)
                    {
                        SelectedElements.Remove(ele);
                        ele.IsSelected = false;
                        return ele;
                    }
                    return null;
                }
            }
            return null;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="container"></param>
        /// <param name="hitPoint"></param>
        /// <param name="selectSize"></param>
        /// <returns>选中的元素，是否是新选中</returns>
        public static Tuple<Element, bool> HitSelect(ElementContainer container, Vector2d hitPoint, double selectSize)
        {
            for (var i = container.Elements.Count - 1; i >= 0; i--)
            {
                var ele = container.Elements[i];
                var testBox = new Box2d(new Vector2d(hitPoint.X - selectSize, hitPoint.Y - selectSize), selectSize * 2, selectSize * 2);
                var intersected = ele.IntersectWithBox(testBox);
                if (intersected)
                {
                    if (ele.IsSelected)
                    {
                        return new Tuple<Element, bool>(ele, false);
                    }
                    else
                    {
                        ele.IsSelected = true;
                        SelectedElements.Add(ele);
                        return new Tuple<Element, bool>(ele, true);
                    }
                }
            }
            return null;
        }


        public static  Element  HoverSelectElement(ElementContainer container, Vector2d hitPoint, double selectSize)
        {
            if (HoveredElement != null)
            {
                HoveredElement.IsHovered = false;
                HoveredElement = null;
            }
            for (var i = container.Elements.Count - 1; i >= 0; i--)
            {
                var ele = container.Elements[i];
                var testBox = new Box2d(new Vector2d(hitPoint.X - selectSize, hitPoint.Y - selectSize), selectSize * 2, selectSize * 2);
                var intersected = ele.IntersectWithBox(testBox);
                if (intersected)
                {
                    ele.IsHovered = true;
                    HoveredElement = ele;
                    return ele;
                }
            }
            return null;
        }
      
        public static void ClearSelects()
        {
            foreach (var ele in SelectedElements)
            {
                ele.IsSelected = false;
            }
            SelectedElements.Clear();
            RuntimeScene.ClearElementGrips();

        }

        public static void SetSelectsToDragging(bool dragging)
        {
            foreach (var ele in SelectedElements)
            {
                ele.IsDragging = dragging;
            }
        }
       
        public static void HoverUnselectElement()
        {
           if(HoveredElement!= null)
            {
                HoveredElement.IsHovered = false;
                HoveredElement = null;
            }
        }

        public static void DrawPasteElments(SKCanvas canvas,SKPoint pointerPos)
        {
            var wp=ElementDrawer.PointScrToWorld(pointerPos);
            var count = PastingElements.Count;
            for (var i = 0; i < count; i++)
            {
                if (i > PastingElements.Count - 1) break;
                PastingElements[i].Draw(canvas, wp);
            }
        }
    }
}
